package gsconfig

import (
	"fmt"
	"reflect"
	"strconv"

	"github.com/spf13/viper"
)

func ParseConfig(configFilePath string, config any) {
	// 先设置默认值
	setDefaults(config)

	viper.SetConfigFile(configFilePath)
	fmt.Println("parse config: " + configFilePath)
	if err := viper.ReadInConfig(); err != nil {
		panic(err)
	}

	err := viper.Unmarshal(config)
	if err != nil {
		panic(err)
	}
}

// 递归地设置结构体字段的默认值
func setDefaults(obj any) {
	val := reflect.ValueOf(obj).Elem()
	typ := val.Type()
	for i := 0; i < val.NumField(); i++ {
		field := val.Field(i)
		fieldType := typ.Field(i)
		// 如果是嵌套结构体或指针，递归处理
		if field.Kind() == reflect.Struct {
			setDefaults(field.Addr().Interface())
		} else if field.Kind() == reflect.Ptr && !field.IsNil() {
			setDefaults(field.Interface())
		} else if field.Kind() == reflect.Map {
			for _, key := range field.MapKeys() {
				mapValue := field.MapIndex(key)
				if mapValue.Kind() == reflect.Ptr && !mapValue.IsNil() {
					setDefaults(mapValue.Interface())
				}
			}
		}

		// 处理默认值
		defaultTag := fieldType.Tag.Get("default")
		if defaultTag != "" && field.IsZero() {
			switch field.Kind() {
			case reflect.String:
				field.SetString(defaultTag)
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				intVal, _ := strconv.ParseInt(defaultTag, 10, 64)
				field.SetInt(intVal)
			case reflect.Bool:
				boolVal, _ := strconv.ParseBool(defaultTag)
				field.SetBool(boolVal)
			case reflect.Float32, reflect.Float64:
				floatVal, _ := strconv.ParseFloat(defaultTag, 64)
				field.SetFloat(floatVal)
			}
		}
	}
}
